﻿namespace com.vs.General
{
    using java.lang;
    using System;
    using System.Collections;
    using System.EnterpriseServices;
    using System.Reflection;
    using System.Text;

    public class ReflectionManager
    {
        private static Hashtable _assemblyPartialNameCache = new Hashtable();

        public static object CreateInstance(string stAssemblyName, string stNamespace, string stClass)
        {
            return CreateInstance(stAssemblyName, stNamespace, stClass, null);
        }

        public T CreateInstance<T>(string assemblyName, string namespaceName, string className)
        {
            return (T) CreateInstance(assemblyName, namespaceName, className);
        }

        public static object CreateInstance(string stAssemblyName, string stNamespace, string stClass, object[] parameters)
        {
            object obj2 = null;
            Assembly assemblyFromPartialName = GetAssemblyFromPartialName(stAssemblyName);
            if (assemblyFromPartialName == null)
            {
                throw new System.Exception("Could not load assembly with partial name " + stAssemblyName);
            }
            obj2 = assemblyFromPartialName.CreateInstance(stNamespace + "." + stClass, false, BindingFlags.CreateInstance, null, parameters, null, null);
            if (obj2 == null)
            {
                throw new System.Exception("Could not create an instance of " + stNamespace + "." + stClass);
            }
            return obj2;
        }

        private static Assembly GetAssemblyFromPartialName(string partialName)
        {
            lock (_assemblyPartialNameCache)
            {
                Assembly assembly = _assemblyPartialNameCache[partialName] as Assembly;
                if (assembly == null)
                {
                    assembly = Assembly.Load(partialName);
                    _assemblyPartialNameCache[partialName] = assembly;
                }
                return assembly;
            }
        }

        public static FieldInfo[] GetFieldInfo(string assemblyName, string path, string className)
        {
            object o = null;
            FieldInfo[] fields;
            try
            {
                o = CreateInstance(assemblyName, path, className);
                fields = o.GetType().GetFields();
            }
            finally
            {
                ReleaseInstance(o);
            }
            return fields;
        }

        public static string[] GetParameterNames(object instance, string stMethod)
        {
            if (instance == null)
            {
                return new string[0];
            }
            MethodInfo method = instance.GetType().GetMethod(stMethod);
            if (method == null)
            {
                return new string[0];
            }
            ParameterInfo[] parameters = method.GetParameters();
            if ((parameters == null) || (parameters.Length <= 0))
            {
                return new string[0];
            }
            string[] strArray = new string[parameters.Length];
            for (int i = 0; i < strArray.Length; i++)
            {
                strArray[i] = parameters[i].Name;
            }
            return strArray;
        }

        public static string[] GetParameterNames(string assemblyName, string namespaceName, string className, string methodName)
        {
            object instance = null;
            string[] parameterNames;
            try
            {
                instance = CreateInstance(assemblyName, namespaceName, className);
                parameterNames = GetParameterNames(instance, methodName);
            }
            finally
            {
                ReleaseInstance(instance);
            }
            return parameterNames;
        }

        public static Type GetType(string typeName)
        {
            string assemblyString = typeName.Substring(typeName.LastIndexOf(",") + 1);
            string name = typeName.Substring(0, typeName.IndexOf(","));
            if (assemblyString.Equals(Assembly.GetExecutingAssembly().GetName().Name))
            {
                return Assembly.GetExecutingAssembly().GetType(name);
            }
            return Assembly.Load(assemblyString).GetType(name);
        }

        public static Type GetType(string dllName, string fullName)
        {
            return Assembly.LoadFrom(dllName).GetType(fullName);
        }

        public static object InvokeMethod(object instance, string stMethod, object[] parameters)
        {
            return InvokeMethod(instance, stMethod, parameters, true);
        }

        public static object InvokeMethod(object instance, string stMethod, object[] parameters, bool mustExist)
        {
            return InvokeMethod(instance.GetType(), instance, stMethod, parameters, mustExist);
        }

        public static object InvokeMethod(Type type, object instance, string stMethod, object[] parameters)
        {
            return InvokeMethod(type, instance, stMethod, parameters, true);
        }

        public static object InvokeMethod(string assemblyName, string namespaceName, string className, string methodName, object[] parameters)
        {
            object instance = null;
            object obj3;
            try
            {
                instance = CreateInstance(assemblyName, namespaceName, className);
                obj3 = InvokeMethod(instance, methodName, parameters, true);
            }
            finally
            {
                ReleaseInstance(instance);
            }
            return obj3;
        }

        public static object InvokeMethod(Type type, object instance, string stMethod, object[] parameters, bool mustExist)
        {
            Type[] types = null;
            if ((parameters != null) && (parameters.Length > 0))
            {
                types = new Type[parameters.Length];
                for (int i = 0; i < parameters.Length; i++)
                {
                    if (parameters[i] is Integer)
                    {
                        parameters[i] = ((Integer) parameters[i]).intValue();
                    }
                    types[i] = parameters[i].GetType();
                }
            }
            MethodInfo method = type.GetMethod(stMethod, types);
            if (method == null)
            {
                if (!mustExist)
                {
                    return null;
                }
                StringBuilder builder = new StringBuilder("Could not find method ").Append(stMethod).Append(" for an instance of ").Append(instance.GetType().ToString());
                if ((types != null) && (types.Length > 0))
                {
                    builder.Append(" with the following parameter type(s): ");
                    foreach (Type type2 in types)
                    {
                        builder.Append(type2.ToString()).Append(",");
                    }
                    builder.Length--;
                }
                throw new System.Exception(builder.ToString());
            }
            return method.Invoke(instance, parameters);
        }

        public static object InvokeMethod(string assemblyName, string namespaceName, string className, string methodName, object[] parameters, bool mustExist)
        {
            object instance = null;
            object obj3;
            try
            {
                instance = CreateInstance(assemblyName, namespaceName, className);
                obj3 = InvokeMethod(instance, methodName, parameters, mustExist);
            }
            finally
            {
                ReleaseInstance(instance);
            }
            return obj3;
        }

        private static void ReleaseInstance(object o)
        {
            if (o != null)
            {
                if (o is ServicedComponent)
                {
                    ((ServicedComponent) o).Dispose();
                }
                else if (o is IDisposable)
                {
                    ((IDisposable) o).Dispose();
                }
            }
        }
    }
}

